Skip to content

feat(storage): sync async with main branch#1744

Open
googlyrahman wants to merge 59 commits intogoogleapis:asyncfrom
googlyrahman:pr-1743
Open

feat(storage): sync async with main branch#1744
googlyrahman wants to merge 59 commits intogoogleapis:asyncfrom
googlyrahman:pr-1743

Conversation

@googlyrahman
Copy link

Sync async with main branch

chandra-siri and others added 30 commits December 9, 2025 13:32
…upload (googleapis#1654)

feat: send entire object checksum in the final api call of resumable
upload

fixes b/461994245

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
feat: Support urllib3 >= 2.6.0

**Context**:
* This library implements a custom decoders ( `_GzipDecoder` ,
`_BrotliDecoder` ) which inherit from `urllib3.response.ContentDecoder`
* Interface of `urllib3.response.ContentDecoder` was changed in
[2.6.0](https://urllib3.readthedocs.io/en/stable/changelog.html#id1) to
fix security vulnerability for highly compressed data reads.
(Decompression bombs)

Hence we need to change our interfaces as well. 

**Changes**
* Add `max_length` param on decompress method, provide default value of
-1 (same as urllib3's decompress)
* Provide backwards compatibility  ( ie urllib3 <= 2.5.0)
🤖 I have created a release *beep* *boop*
---


##
[3.7.0](googleapis/python-storage@v3.6.0...v3.7.0)
(2025-12-09)


### Features

* Auto enable mTLS when supported certificates are detected
([googleapis#1637](googleapis#1637))
([4e91c54](googleapis@4e91c54))
* Send entire object checksum in the final api call of resumable upload
([googleapis#1654](googleapis#1654))
([ddce7e5](googleapis@ddce7e5))
* Support urllib3 &gt;= 2.6.0
([googleapis#1658](googleapis#1658))
([57405e9](googleapis@57405e9))


### Bug Fixes

* **bucket:** Move blob fails when the new blob name contains characters
that need to be url encoded
([googleapis#1605](googleapis#1605))
([ec470a2](googleapis@ec470a2))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Chandra Shekhar Sirimala <chandrasiri@google.com>
chore: add gcs-fs as CODEOWNERS
fix: close write object stream always. 

otherwise Task will remain for long time until GC kills it and it'll
throw this `"Task was destroyed but it is pending!"`
…oogleapis#1636)

fix(experimental): no state lookup while opening bidi-write stream
This PR adds support for Python 3.14 to the library.

Key changes include:
- Updating `setup.py` to include the Python 3.14 classifier.
- Updating `testing/constraints-3.14.txt` to specify `grpcio >= 1.75.1`.
- Updating `noxfile.py` to include 3.14 sessions and set default to
3.14.
- Updating `.github/sync-repo-settings.yaml` to include 3.14 in required
checks.

Tests were run locally using the `python-multi` Docker image for Python
3.9 and 3.14. Some unit tests failed due to environment issues within
the container, but these are not expected to occur in the CI
environment.

---------

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
Co-authored-by: Anthonios Partheniou <partheniou@google.com>
…nt (googleapis#1668)

skip failing samples due to public access prevention enforcement. 

More Details on b/469643064
chore: add system test for cloud path
chore: add system 3.9 tests as required
feat: expose persisted size in MRD (MultiRangeReader)
fix: add system test for opening with read_handle
chore: Prevent OS Login key accumulation in e2e tests
feat: compute chunk wise checksum for bidi_writes and send it via
BidiWriteObjectRequest

As a part of this change, also did a small refactoring 
  *  Moved the precondition check to __utils.py_ file
feat: make flush size configurable
chore: skip kms tests until b/470276398

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…nning zonal system tests (googleapis#1691)

chore: optimization to reduce number of open TCP connections while
running zonal system tests

1. Increase `ulimit -n 10000` before ssh'ing into the VM where system
tests for zonal buckets are running.
2. Delete `mrd` and `writer` instance and trigger `gc.collect()` ( this
alone should suffice but increasing doing the above optimization to
avoid future issues.
feat: implement `append_from_file`
chore:delete topic after creation

part of b/470069573
…is#1694)

Revert "skip notification tests until b/470069573 is fixed"
- Add bidi stream retry manager. It will the main class that would be
responsible for retries.
- Integrate MRD with bidi stream retry manager and reads resumption
strategy
- Added conformance tests for all error scenarios and smart resumption
for bidi reads
- Refactored MRD's `download_ranges()` method, which will now use retry
manager's `execute()` method to send the requests
- Modified the logic to parse and handle the
`BidiReadObjectRedirectedError`.
- Modified cloud build configuration to also pull the latest changes of
the current PR.
- Formatted few more files using black formatter
…h generation (googleapis#1698)

chore(tests): add test for reading unfinalized appendable objects with
generation
Adding writes resumption strategy which will be used for error handling
of bidi writes operation.
…#1699)

Earlier the last chunk was being flushed while calling the close()
method. Now it will be done inside the append method itself.
Bump the current version in `.librarian/state.yaml` to `3.7.0` to cater
for googleapis#1621 which was
released on December 9 2025.

This will address the issue in
googleapis#1701 where librarian
sets the version to `3.7.0` which has already been released.

The reason that this manual PR is needed is because the release on
December 9th used a different tool `release-please` which does not
update the `.librarian/state.yaml` file.
)

PR created by the Librarian CLI to initialize a release. Merging this PR
will auto trigger a release.

Librarian Version: v0.7.0
Language Image:
us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:8e2c32496077054105bd06c54a59d6a6694287bc053588e24debe6da6920ad91
<details><summary>google-cloud-storage: 3.8.0</summary>

##
[3.8.0](googleapis/python-storage@v3.7.0...v3.8.0)
(2026-01-13)

### Features

* expose persisted size in mrd (googleapis#1671)
([0e2961b](googleapis@0e2961be))

* implement &googleapis#34;append_from_file&googleapis#34; (googleapis#1686)
([1333c95](googleapis@1333c956))

* compute chunk wise checksum for bidi_writes (googleapis#1675)
([139390c](googleapis@139390cb))

* flush the last chunk in append method (googleapis#1699)
([89bfe7a](googleapis@89bfe7a5))

* add write resumption strategy (googleapis#1663)
([a57ea0e](googleapis@a57ea0ec))

* add bidi stream retry manager. (googleapis#1632)
([d90f0ee](googleapis@d90f0ee0))

* make flush size configurable (googleapis#1677)
([f7095fa](googleapis@f7095faf))

### Bug Fixes

* no state lookup while opening bidi-write stream
([2d5a7b1](googleapis@2d5a7b16))

* no state lookup while opening bidi-write stream (googleapis#1636)
([2d5a7b1](googleapis@2d5a7b16))

* close write object stream always (googleapis#1661)
([4a609a4](googleapis@4a609a4b))

* add system test for opening with read_handle (googleapis#1672)
([6dc711d](googleapis@6dc711da))

</details>

---------

Co-authored-by: Victor Chudnovsky <vchudnov@google.com>
…quests in async streams. Gracefully close streams. (googleapis#1700)

fix(experimental): implement requests_done method to signal end of
requests in async streams. Gracefully close streams.
…ng existing objects and add `is_stream_open` support (googleapis#1709)

feat(ZonalBuckets): add support for `generation=0` to prevent
overwriting existing objects
feat(ZonalBuckets): add `is_stream_open` property to
AsyncAppendableObjectWriter for stream status check

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…oogleapis#1705)

feat(samples): add samples for appendable objects writes and reads

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Pulkit0110 and others added 15 commits January 29, 2026 16:09
Adding a support to pass `generation` in the constructor of MRD. It is
done to make it compatible with the other public interfaces.

Earlier, `generation_number` was exposed as the parameter which would
still be valid after these changes. But using `generation` is more
preferred.
Expose `DELETE_OBJECT`   in `AsyncGrpcClient`
When `writer.close()` is called without setting finalize_on_close flag,
we need to get two responses:
1) to get the persisted_size
2) eof response

That's why added a check if the first response is not eof, then again
receive the response from the stream.
chore: Add README for running zonal buckets samples
This method can be used to fetch the metadata of an object using the
async grpc API.
)

PR created by the Librarian CLI to initialize a release. Merging this PR
will auto trigger a release.

Librarian Version: v1.0.2-0.20251119154421-36c3e21ad3ac
Language Image:
us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:8e2c32496077054105bd06c54a59d6a6694287bc053588e24debe6da6920ad91
<details><summary>google-cloud-storage: 3.9.0</summary>

##
[3.9.0](googleapis/python-storage@v3.8.0...v3.9.0)
(2026-02-02)

### Features

* update generation for MRD (googleapis#1730)
([08bc708](googleapis@08bc7082))

* add get_object method for async grpc client (googleapis#1735)
([0e5ec29](googleapis@0e5ec29b))

* Add micro-benchmarks for reads comparing standard (regional) vs rapid
(zonal) buckets. (googleapis#1697)
([1917649](googleapis@1917649f))

* Add support for opening via `write_handle` and fix `write_handle` type
(googleapis#1715)
([2bc15fa](googleapis@2bc15fa5))

* add samples for appendable objects writes and reads
([2e1a1eb](googleapis@2e1a1eb5))

* add samples for appendable objects writes and reads (googleapis#1705)
([2e1a1eb](googleapis@2e1a1eb5))

* add context manager to mrd (googleapis#1724)
([5ac2808](googleapis@5ac2808a))

* Move Zonal Buckets features of `_experimental` (googleapis#1728)
([74c9ecc](googleapis@74c9ecc5))

* add default user agent for grpc (googleapis#1726)
([7b31946](googleapis@7b319469))

* expose finalized_time in blob.py applicable for GET_OBJECT in ZB
(googleapis#1719)
([8e21a7f](googleapis@8e21a7fe))

* expose `DELETE_OBJECT` in `AsyncGrpcClient` (googleapis#1718)
([c8dd7a0](googleapis@c8dd7a0b))

* send `user_agent` to grpc channel (googleapis#1712)
([cdb2486](googleapis@cdb2486b))

* integrate writes strategy and appendable object writer (googleapis#1695)
([dbd162b](googleapis@dbd162b3))

* Add micro-benchmarks for writes comparing standard (regional) vs rapid
(zonal) buckets. (googleapis#1707)
([dbe9d8b](googleapis@dbe9d8b8))

* add support for `generation=0` to avoid overwriting existing objects
and add `is_stream_open` support (googleapis#1709)
([ea0f5bf](googleapis@ea0f5bf8))

* add support for `generation=0` to prevent overwriting existing objects
([ea0f5bf](googleapis@ea0f5bf8))

* add `is_stream_open` property to AsyncAppendableObjectWriter for
stream status check
([ea0f5bf](googleapis@ea0f5bf8))

### Bug Fixes

* receive eof while closing reads stream (googleapis#1733)
([2ef6339](googleapis@2ef63396))

* update write handle on every recv() (googleapis#1716)
([5d9fafe](googleapis@5d9fafe1))

* implement requests_done method to signal end of requests in async
streams. Gracefully close streams. (googleapis#1700)
([6c16079](googleapis@6c160794))

* implement requests_done method to signal end of requests in async
streams. Gracefully close streams.
([6c16079](googleapis@6c160794))

* instance grpc client once per process in benchmarks (googleapis#1725)
([721ea2d](googleapis@721ea2dd))

* Fix formatting in setup.py dependencies list (googleapis#1713)
([cc4831d](googleapis@cc4831d7))

* Change contructors of MRD and AAOW AsyncGrpcClient.grpc_client to
AsyncGrpcClient (googleapis#1727)
([e730bf5](googleapis@e730bf50))

</details>
Automated: Migrate {target_path} from gsutil to gcloud storage

This CL is part of the on going effort to migrate from the legacy
`gsutil` tool to the new and improved `gcloud storage` command-line
interface.
`gcloud storage` is the recommended and modern tool for interacting with
Google Cloud Storage, offering better performance, unified
authentication, and a more consistent command structure with other
`gcloud` components. 🚀

### Automation Details

This change was **generated automatically** by an agent that targets
users of `gsutil`.
The transformations applied are based on the [gsutil to gcloud storage
migration guide](http://go/gsutil-gcloud-storage-migration-guide).

### ⚠️ Action Required: Please Review and Test Carefully

While we have based the automation on the migration guide, every use
case is unique.
**It is crucial that you thoroughly test these changes in environments
appropriate to your use-case before merging.**
Be aware of potential differences between `gsutil` and `gcloud storage`
that could impact your workflows.
For instance, the structure of command output may have changed,
requiring updates to any scripts that parse it. Similarly, command
behavior can differ subtly; the `gcloud storage rsync` command has a
different file deletion logic than `gsutil rsync`, which could lead to
unintended file deletions.

Our migration guides can help guide you through a list of mappings and
some notable differences between the two tools.

Standard presubmit tests are run as part of this CL's workflow. **If you
need to target an additional test workflow or require assistance with
testing, please let us know.**

Please verify that all your Cloud Storage operations continue to work as
expected to avoid any potential disruptions in production.

### Support and Collaboration

The `GCS CLI` team is here to help! If you encounter any issues, have a
complex use case that this automated change doesn't cover, or face any
other blockers, please don't hesitate to reach out.
We are happy to work with you to test and adjust these changes as
needed.

**Contact:** `gcs-cli-hyd@google.com`

We appreciate your partnership in this important migration effort!

#gsutil-migration

Co-authored-by: Chandra Shekhar Sirimala <chandrasiri@google.com>
Add a warning that generation_number will be deprecated in the next
major release.
The PR sync the main and async branch.

---------

Co-authored-by: Chandra Shekhar Sirimala <chandrasiri@google.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Co-authored-by: Chalmer Lowe <chalmerlowe@google.com>
Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
Co-authored-by: Anthonios Partheniou <partheniou@google.com>
Adds async credential wrapper for async client. 

Context:

- The standard google auth credentials are currently synchronous, and
it's asynchronous credentials classes are either not available or marked
private.
- Credential retrieval and refreshing will remain synchronous under the
hood. Rationale: As authentication tokens typically possess an
expiration lifetime of one hour, the blocking time required for token
fetching occurs infrequently. The performance impact of blocking (or
utilizing a separate thread for offloading) once per hour is deemed
negligible when weighed against the considerable engineering cost of
developing and maintaining a asynchronous authentication.
…leapis#1655)

This PR introduces an abstract class to support the upcoming async
client for the Python SDK. This refactor defines the public interface
and enables code sharing between sync and async client, without
introducing new logic.
…oogleapis#1696)

1. Add async client implementation.
2. Add AsyncHTTPIterator deriving from
google.api_core.page_iterator_async.AsyncIterator as an alternative to
google.api_core.page_iterator.HTTPIterator

The AsyncHTTPIterator doesn't exists, and hence needs to be implemented.
@product-auto-label product-auto-label bot added size: xl Pull request size is extra large. api: storage Issues related to the googleapis/python-storage API. labels Feb 5, 2026
@googlyrahman googlyrahman changed the title Sync async with main branch feat(storage): Sync async with main branch Feb 5, 2026
@googlyrahman googlyrahman changed the title feat(storage): Sync async with main branch feat(storage): sync async with main branch Feb 5, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @googlyrahman, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request integrates a substantial set of enhancements and new features for the asynchronous gRPC client within the Google Cloud Storage library. The core focus is on improving the reliability and functionality of interactions with Zonal Buckets and appendable objects, moving previously experimental APIs to a stable state. It also lays the groundwork for robust performance evaluation through new benchmarking tools.

Highlights

  • API Stabilization and Migration: Experimental asynchronous gRPC client modules and related utilities have been moved to stable paths within google.cloud.storage.asyncio, with deprecation warnings added to the old experimental locations. This indicates a significant step towards stabilizing these features.
  • Enhanced Asynchronous gRPC Client: The AsyncGrpcClient now includes new methods for get_object and delete_object, expanding its capabilities for managing Google Cloud Storage objects asynchronously. It also incorporates a default user agent for gRPC channels.
  • Robust Bidirectional Stream Retry Mechanisms: Comprehensive retry logic has been implemented for both AsyncAppendableObjectWriter (for writes) and AsyncMultiRangeDownloader (for reads). This includes strategies for handling BidiWriteObjectRedirectedError and BidiReadObjectRedirectedError, ensuring more resilient data transfers over gRPC bidirectional streams.
  • Zonal Buckets and Appendable Object Support: New features related to Zonal Buckets and appendable objects have been moved from experimental status. This includes support for generation=0 to prevent accidental overwrites, a finalized_time property in blob.py, and new samples demonstrating creation, finalization, pausing/resuming, and tailing of appendable objects, as well as multi-range downloads.
  • Performance Micro-benchmarking Infrastructure: A new micro-benchmarking framework has been introduced to compare read and write performance between standard (regional) and rapid (zonal) buckets. This includes utilities for resource monitoring and JSON to CSV conversion for analysis.
  • CI/CD and Testing Improvements: Kokoro and Cloud Build scripts have been updated to support zonal bucket system tests, including increasing the ulimit for gRPC bidirectional streams. New conformance tests for bidi reads and writes with fault injection have also been added to ensure reliability under various network conditions.
Changelog
  • .gitignore
    • Added __benchmark_results__/** to ignore benchmarking output files.
  • .kokoro/trampoline_v2.sh
    • Updated gsutil cp commands to gcloud storage cp.
    • Added gcloud storage cp commands for secrets and automl files.
  • .librarian/state.yaml
    • Updated google-cloud-storage library version from 3.6.0 to 3.9.0.
  • CHANGELOG.md
    • Added detailed changelog entries for versions 3.9.0 and 3.8.0, including numerous features and bug fixes related to async gRPC client, appendable objects, zonal buckets, and retry mechanisms.
  • cloudbuild/run_zonal_tests.sh
    • Added git fetch origin "refs/pull/${_PR_NUMBER}/head" to fetch PR head for testing.
    • Added logging for current ulimit before running zonal tests.
    • Added execution of zonal snippets tests (samples/snippets/zonal_buckets/zonal_snippets_test.py).
  • cloudbuild/zb-system-tests-cloudbuild.yaml
    • Added _ULIMIT substitution variable with a default value of 10000 for gRPC bidi streams.
    • Modified gcloud compute ssh command to set the ulimit on the VM before running zonal tests.
  • google/cloud/_storage_v2/gapic_version.py
    • Updated __version__ to 3.9.0.
  • google/cloud/storage/_experimental/asyncio/_utils.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio._utils.
  • google/cloud/storage/_experimental/asyncio/async_abstract_object_stream.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.async_abstract_object_stream.
  • google/cloud/storage/_experimental/asyncio/async_appendable_object_writer.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.async_appendable_object_writer.
  • google/cloud/storage/_experimental/asyncio/async_client.py
    • Applied minor formatting changes to imports and method calls.
    • Adjusted AsyncCredsWrapper instantiation and close method logic for clarity.
  • google/cloud/storage/_experimental/asyncio/async_creds.py
    • Applied minor formatting changes to imports and the refresh method.
  • google/cloud/storage/_experimental/asyncio/async_grpc_client.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.async_grpc_client.
  • google/cloud/storage/_experimental/asyncio/async_helpers.py
    • Applied minor formatting changes to imports and method calls.
  • google/cloud/storage/_experimental/asyncio/async_multi_range_downloader.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.async_multi_range_downloader.
  • google/cloud/storage/_experimental/asyncio/async_read_object_stream.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.async_read_object_stream.
  • google/cloud/storage/_experimental/asyncio/async_write_object_stream.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.async_write_object_stream.
  • google/cloud/storage/_experimental/asyncio/retry/_helpers.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.retry._helpers.
  • google/cloud/storage/_experimental/asyncio/retry/base_strategy.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.retry.base_strategy.
  • google/cloud/storage/_experimental/asyncio/retry/bidi_stream_retry_manager.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.retry.bidi_stream_retry_manager.
  • google/cloud/storage/_experimental/asyncio/retry/reads_resumption_strategy.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.retry.reads_resumption_strategy.
  • google/cloud/storage/_experimental/asyncio/retry/writes_resumption_strategy.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.asyncio.retry.writes_resumption_strategy.
  • google/cloud/storage/_experimental/grpc_client.py
    • Added DeprecationWarning and imported all from the new stable module google.cloud.storage.grpc_client.
  • google/cloud/storage/_media/requests/download.py
    • Applied minor formatting changes.
  • google/cloud/storage/abstracts/base_client.py
    • Applied minor formatting changes to imports and property definitions.
  • google/cloud/storage/asyncio/_utils.py
    • New file: Contains raise_if_no_fast_crc32c to check for C-accelerated crc32c and update_write_handle_if_exists.
  • google/cloud/storage/asyncio/async_abstract_object_stream.py
    • New file: Defines _AsyncAbstractObjectStream, an abstract base class for gRPC bidi-streams.
  • google/cloud/storage/asyncio/async_appendable_object_writer.py
    • New file: Implements AsyncAppendableObjectWriter for appending data to GCS objects asynchronously, including retry logic and flush interval configuration.
  • google/cloud/storage/asyncio/async_grpc_client.py
    • New file: Implements AsyncGrpcClient, an asynchronous client for gRPC API, with delete_object and get_object methods, and user agent handling.
  • google/cloud/storage/asyncio/async_multi_range_downloader.py
    • New file: Implements AsyncMultiRangeDownloader for concurrent multi-range downloads, including retry mechanisms and context manager support.
  • google/cloud/storage/asyncio/async_read_object_stream.py
    • New file: Implements _AsyncReadObjectStream for reading data from GCS objects via gRPC bidi-streams, including metadata handling and requests_done method.
  • google/cloud/storage/asyncio/async_write_object_stream.py
    • New file: Implements _AsyncWriteObjectStream for writing data to GCS appendable objects via gRPC bidi-streams, including handling generation numbers and write handles.
  • google/cloud/storage/asyncio/retry/_helpers.py
    • New file: Contains helper functions _handle_redirect and _extract_bidi_writes_redirect_proto for parsing gRPC redirect errors.
  • google/cloud/storage/asyncio/retry/base_strategy.py
    • New file: Defines _BaseResumptionStrategy, an abstract base class for bidi stream resumption strategies.
  • google/cloud/storage/asyncio/retry/bidi_stream_retry_manager.py
    • New file: Implements _BidiStreamRetryManager to manage generic retry loops for bidi streaming operations.
  • google/cloud/storage/asyncio/retry/reads_resumption_strategy.py
    • New file: Implements _ReadResumptionStrategy for handling resumption logic for bidi reads, including offset and checksum verification.
  • google/cloud/storage/asyncio/retry/writes_resumption_strategy.py
    • New file: Implements _WriteResumptionStrategy for handling resumption logic for bidi writes, including chunking, checksums, and flush logic.
  • google/cloud/storage/blob.py
    • Added finalized_time property to Blob class, returning the time a soft-deleted object will be permanently deleted.
  • google/cloud/storage/client.py
    • Applied minor formatting changes to imports and connection handling.
  • google/cloud/storage/grpc_client.py
    • New file: Implements GrpcClient, a synchronous client for gRPC API.
  • google/cloud/storage/version.py
    • Updated __version__ to 3.9.0.
  • noxfile.py
    • Added pytest-asyncio, grpcio, grpcio-status, and grpc-google-iam-v1 to testing dependencies for system and conformance tests.
  • samples/README.md
    • Updated instructions to include running samples for Zonal Buckets, specifying google-cloud-storage[grpc] installation.
  • samples/generated_samples/snippet_metadata_google.storage.v2.json
    • Updated version to 3.9.0.
  • samples/snippets/notification_polling.py
    • Updated gsutil commands to gcloud storage commands for creating buckets and notifications.
  • samples/snippets/snippets_test.py
    • Added sys import.
    • Added @pytest.mark.skipif(IS_PYTHON_3_14, reason="b/470276398") to several tests to skip them on Python 3.14 due to a known issue.
  • samples/snippets/storage_get_metadata.py
    • Added Blob finalization: {blob.finalized_time} to the output of blob_metadata function.
  • samples/snippets/zonal_buckets/README.md
    • New file: Provides documentation and usage examples for Zonal Buckets snippets.
  • samples/snippets/zonal_buckets/storage_create_and_write_appendable_object.py
    • New file: Sample code for creating and writing to an appendable object in a zonal bucket.
  • samples/snippets/zonal_buckets/storage_finalize_appendable_object_upload.py
    • New file: Sample code for creating, writing to, and finalizing an appendable object.
  • samples/snippets/zonal_buckets/storage_open_multiple_objects_ranged_read.py
    • New file: Sample code for downloading ranges from multiple objects concurrently.
  • samples/snippets/zonal_buckets/storage_open_object_multiple_ranged_read.py
    • New file: Sample code for downloading multiple ranges from a single object.
  • samples/snippets/zonal_buckets/storage_open_object_read_full_object.py
    • New file: Sample code for downloading the entire content of an object using AsyncMultiRangeDownloader.
  • samples/snippets/zonal_buckets/storage_open_object_single_ranged_read.py
    • New file: Sample code for downloading a single range of bytes from an object.
  • samples/snippets/zonal_buckets/storage_pause_and_resume_appendable_upload.py
    • New file: Sample code demonstrating how to pause and resume an appendable object upload.
  • samples/snippets/zonal_buckets/storage_read_appendable_object_tail.py
    • New file: Sample code for tailing an appendable GCS object, simulating tail -f.
  • samples/snippets/zonal_buckets/zonal_snippets_test.py
    • New file: System tests for the new zonal buckets snippets, including fixtures for async gRPC clients and object creation/cleanup.
  • setup.py
    • Added testing extra dependencies, including pytest-asyncio, grpcio, grpcio-status, grpc-google-iam-v1, and various benchmarking tools.
  • tests/conformance/test_bidi_reads.py
    • New file: Conformance tests for bidi reads, including fault injection scenarios for retries and redirects.
  • tests/conformance/test_bidi_writes.py
    • New file: Conformance tests for bidi writes, including fault injection scenarios for retries and redirects.
  • tests/perf/microbenchmarks/README.md
    • New file: Documentation for performance microbenchmarks, including usage, configuration, and output instructions.
  • tests/perf/microbenchmarks/init.py
    • New file: Empty __init__.py for the microbenchmarks package.
  • tests/perf/microbenchmarks/_utils.py
    • New file: Utility functions for microbenchmarks, including publish_benchmark_extra_info and RandomBytesIO.
  • tests/perf/microbenchmarks/conftest.py
    • New file: Pytest fixtures for microbenchmarks, including blobs_to_delete, storage_client, monitor, publish_resource_metrics, and workload_params.
  • tests/perf/microbenchmarks/json_to_csv.py
    • New file: Script to convert pytest-benchmark JSON output to a CSV report.
  • tests/perf/microbenchmarks/parameters.py
    • New file: Dataclass IOBenchmarkParameters for defining common benchmark parameters.
  • tests/perf/microbenchmarks/reads/config.py
    • New file: Configuration logic for generating read benchmark parameters from config.yaml.
  • tests/perf/microbenchmarks/reads/config.yaml
    • New file: YAML configuration file defining read benchmark workloads and common parameters.
  • tests/perf/microbenchmarks/reads/parameters.py
    • New file: Dataclass ReadParameters extending IOBenchmarkParameters with a pattern field.
  • tests/perf/microbenchmarks/reads/test_reads.py
    • New file: Microbenchmarks for GCS read operations, covering single/multi-process and single/multi-coroutine scenarios.
  • tests/perf/microbenchmarks/resource_monitor.py
    • New file: ResourceMonitor class for tracking CPU, memory, and network usage during benchmarks.
  • tests/perf/microbenchmarks/writes/config.py
    • New file: Configuration logic for generating write benchmark parameters from config.yaml.
  • tests/perf/microbenchmarks/writes/config.yaml
    • New file: YAML configuration file defining write benchmark workloads and common parameters.
  • tests/perf/microbenchmarks/writes/parameters.py
    • New file: Dataclass WriteParameters extending IOBenchmarkParameters.
  • tests/perf/microbenchmarks/writes/test_writes.py
    • New file: Microbenchmarks for GCS write operations, covering single/multi-process and single/multi-coroutine scenarios.
  • tests/system/test_notification.py
    • Updated notification_topic fixture to ensure the Pub/Sub topic is deleted after tests, improving cleanup reliability.
  • tests/system/test_zonal.py
    • Updated zonal system tests to use session-scoped event loops and gRPC clients.
    • Added new tests for AsyncAppendableObjectWriter covering basic write/read, sliced writes, non-default flush intervals, and generation=0 behavior.
    • Added tests for AsyncMultiRangeDownloader including reading unfinalized objects and using read handles.
    • Added a test for AsyncGrpcClient.delete_object.
  • tests/unit/asyncio/retry/test_bidi_stream_retry_manager.py
    • New file: Unit tests for _BidiStreamRetryManager, verifying retry logic for initial and mid-stream failures.
  • tests/unit/asyncio/retry/test_reads_resumption_strategy.py
    • New file: Unit tests for _ReadResumptionStrategy, covering request generation, state updates, checksum/offset verification, and redirect handling.
  • tests/unit/asyncio/retry/test_writes_resumption_strategy.py
    • New file: Unit tests for _WriteResumptionStrategy, covering request generation, checksums, flush logic, state updates, and recovery from failures/redirects.
  • tests/unit/asyncio/test_async_appendable_object_writer.py
    • Updated unit tests for AsyncAppendableObjectWriter, including comprehensive tests for _is_write_retryable, initialization validation, stream lifecycle, append logic, flush/close/finalize behavior, and helper methods.
  • tests/unit/asyncio/test_async_client.py
    • Applied minor formatting changes.
    • Updated tests for AsyncClient constructor and _async_http property.
  • tests/unit/asyncio/test_async_creds.py
    • Applied minor formatting changes.
    • Updated tests for AsyncCredsWrapper to ensure correct patching and behavior.
  • tests/unit/asyncio/test_async_grpc_client.py
    • Updated unit tests for AsyncGrpcClient, including detailed checks for user agent handling, client info, and new delete_object and get_object methods with all parameters.
  • tests/unit/asyncio/test_async_helpers.py
    • Applied minor formatting changes.
    • Updated tests for AsyncHTTPIterator to ensure correct iteration, pagination, max results, and extra parameters handling.
  • tests/unit/asyncio/test_async_multi_range_downloader.py
    • Updated unit tests for AsyncMultiRangeDownloader, including generation_number deprecation, _make_mock_mrd helper, and async context manager tests.
  • tests/unit/asyncio/test_async_read_object_stream.py
    • Updated unit tests for _AsyncReadObjectStream, including requests_done method and metadata handling in open.
  • tests/unit/asyncio/test_async_write_object_stream.py
    • Updated unit tests for _AsyncWriteObjectStream, including metadata merging in open and detailed close behavior with grpc.aio.EOF.
  • tests/unit/test_blob.py
    • Added unit tests for the new finalized_time property in Blob.
  • tests/unit/test_grpc_client.py
    • Updated unit tests for GrpcClient constructor and properties.
Activity
  • The pull request title and body indicate a synchronization effort, suggesting a merge of recent developments into the main branch.
  • Numerous new files have been added, particularly under google/cloud/storage/asyncio and tests/perf/microbenchmarks, indicating the introduction of significant new asynchronous gRPC features and their associated testing infrastructure.
  • Existing experimental async modules have been updated with deprecation warnings, pointing to new stable locations, which implies a maturation of these APIs.
  • Version numbers across multiple files (.librarian/state.yaml, CHANGELOG.md, google/cloud/_storage_v2/gapic_version.py, google/cloud/storage/version.py) have been updated to 3.9.0, signifying a major release or update.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request represents a significant synchronization of the async implementation with the main branch, promoting many experimental features to stable. Key changes include moving async modules out of the _experimental namespace, adding get_object and delete_object to the AsyncGrpcClient, and introducing comprehensive retry and resumption strategies for bidi streams. The PR also includes a substantial number of new system tests, conformance tests, and performance microbenchmarks to validate these features. I've identified a few minor issues in the changelog and a docstring that could be improved for clarity.

* Add micro-benchmarks for reads comparing standard (regional) vs rapid (zonal) buckets. (#1697) ([1917649fac41481da1adea6c2a9f4ab1298a34c4](https://github.com/googleapis/python-storage/commit/1917649fac41481da1adea6c2a9f4ab1298a34c4))
* send `user_agent` to grpc channel (#1712) ([cdb2486bb051dcbfbffc2510aff6aacede5e54d3](https://github.com/googleapis/python-storage/commit/cdb2486bb051dcbfbffc2510aff6aacede5e54d3))
* add samples for appendable objects writes and reads (#1705) ([2e1a1eb5cbe1c909f1f892a0cc74fe63c8ef36ff](https://github.com/googleapis/python-storage/commit/2e1a1eb5cbe1c909f1f892a0cc74fe63c8ef36ff))
* add samples for appendable objects writes and reads ([2e1a1eb5cbe1c909f1f892a0cc74fe63c8ef36ff](https://github.com/googleapis/python-storage/commit/2e1a1eb5cbe1c909f1f892a0cc74fe63c8ef36ff))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This changelog entry is a duplicate of the one on the previous line. Please remove it to avoid redundancy.

Comment on lines +27 to +28
* add support for `generation=0` to prevent overwriting existing objects ([ea0f5bf8316f4bfcff2728d9d1baa68dde6ebdae](https://github.com/googleapis/python-storage/commit/ea0f5bf8316f4bfcff2728d9d1baa68dde6ebdae))
* add `is_stream_open` property to AsyncAppendableObjectWriter for stream status check ([ea0f5bf8316f4bfcff2728d9d1baa68dde6ebdae](https://github.com/googleapis/python-storage/commit/ea0f5bf8316f4bfcff2728d9d1baa68dde6ebdae))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These two entries are redundant as they are already covered by the more comprehensive entry on line 26. Please remove them to improve clarity.

* update write handle on every recv() (#1716) ([5d9fafe1466b5ccb1db4a814967a5cc8465148a2](https://github.com/googleapis/python-storage/commit/5d9fafe1466b5ccb1db4a814967a5cc8465148a2))
* Fix formatting in setup.py dependencies list (#1713) ([cc4831d7e253b265b0b96e08b5479f4c759be442](https://github.com/googleapis/python-storage/commit/cc4831d7e253b265b0b96e08b5479f4c759be442))
* implement requests_done method to signal end of requests in async streams. Gracefully close streams. (#1700) ([6c160794afded5e8f4179399f1fe5248e32bf707](https://github.com/googleapis/python-storage/commit/6c160794afded5e8f4179399f1fe5248e32bf707))
* implement requests_done method to signal end of requests in async streams. Gracefully close streams. ([6c160794afded5e8f4179399f1fe5248e32bf707](https://github.com/googleapis/python-storage/commit/6c160794afded5e8f4179399f1fe5248e32bf707))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This changelog entry is a duplicate of the one on the previous line. Please remove it.

Comment on lines +5039 to +5045
"""If this object has been soft-deleted, returns the time at which it will be permanently deleted.

:rtype: :class:`datetime.datetime` or ``NoneType``
:returns:
(readonly) The time that the object will be permanently deleted.
Note this property is only set for soft-deleted objects.
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The docstring for the finalized_time property appears to be incorrect. It states that this property is for soft-deleted objects, which is confusingly similar to the purpose of hard_delete_time. The finalizedTime field in the API typically refers to when an object's generation was fixed (e.g., for appendable objects). Please update the docstring to accurately describe this property to avoid confusion for users.

        """The time at which the object became finalized and its generation was fixed.

        See: https://cloud.google.com/storage/docs/json_api/v1/objects#finalizedTime

        :rtype: :class:`datetime.datetime` or ``NoneType``
        :returns:
            (readonly) The time that the object was finalized.
            Note this property is only set for objects that have been finalized.
        """

@googlyrahman googlyrahman marked this pull request as ready for review February 5, 2026 13:07
@googlyrahman googlyrahman requested review from a team as code owners February 5, 2026 13:07
@snippet-bot
Copy link

snippet-bot bot commented Feb 5, 2026

Here is the summary of changes.

You are about to add 8 region tags.

This comment is generated by snippet-bot.
If you find problems with this result, please file an issue at:
https://github.com/googleapis/repo-automation-bots/issues.
To update this comment, add snippet-bot:force-run label or use the checkbox below:

  • Refresh this comment

@googlyrahman googlyrahman enabled auto-merge (squash) February 5, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: storage Issues related to the googleapis/python-storage API. size: xl Pull request size is extra large.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants